var createError = require('http-errors')
var express = require('express')
//捕捉全局错误
require('express-async-errors')
var path = require('path')
var cookieParser = require('cookie-parser')
var logger = require('morgan')
var config = require('./config/config')
var redis = require('./db/redis')
var pu = require('./tool/public')
var app = express()
var bodyParser = require('body-parser')
require('./tool/wxResult')
let modules = require('./tool/module')
// view engine setup
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'jade')
app.use(logger('tiny'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, 'public')))

// require("./tool/map").getaddress()

/*token验证及所有请求处理*/
app.use('*', async (req, res, next) => {
    console.log(req.headers['x-real-ip'])
    if (req.method != 'GET' && req.method != 'OPTIONS' && req.method != 'POST') {
        res.status(502)
        res.end()
        return
    }
    //json
    res.header('Content-Type', 'application/json;charset=UTF-8')

    /*请求头校验*/
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Headers', 'content-type,token,userid,platform,server,function,team,uid,module')
    res.header('Access-Control-Allow-Methods', '*')
    if (req.method == 'GET' || req.method == 'OPTIONS') {
        next()
        return
    }
    // 解压
    // pu.schemadecode(req.body)
    // console.log(pu.schemadecode(),2454545);
    // console.log(pu.schemadecode(req.headers),5552);
    // req.headers = pu.schemadecode(req.headers)
    // req.body = pu.schemadecode(req.body)
    // console.log('BODY', JSON.stringify(req.body))
    console.log('HEADERS', `${req.method} module:${req.headers.module}  server:${req.headers.server}  function:${req.headers.function}  url:${req.headers.server}/${req.headers.function} uid ${req.headers.uid} team ${req.headers.team}`)
    /*登录信息校验*/
    let url = req.baseUrl.split('/')
    if (!req.headers.server || req.headers.server != url[1]) {
        pu.fail('request server error ', res)
        return
    }
    if (!req.headers.function || req.headers.function != url[2]) {
        pu.fail('request function error ', res)
        return
    }
    for (var i = 0; i < modules.length; i++) {
        for (var j = 0; j < modules[i].jur.length; j++) {
            if (req.headers.server == modules[i].jur[j].server) {
                if (modules[i].module !== req.headers.module) {
                    pu.fail('request module error ', res)
                    return
                    break
                }

            }

        }

    }

    /*token白名单*/
    let Whitelist = config.Whitelist
    var white = false
    for (var i = 0; i < Whitelist.length; i++) {
        if (req.headers.server == Whitelist[i][0]) {
            if (Whitelist[i][1] == '*') { //跳出全部
                white = true
            }
            if (req.headers.function == Whitelist[i][1]) {
                white = true
            }
        }
    }
    if (white) {
        next()
        return
    } else if (white === false) {
        if (!req.headers.userid) {
            pu.error('Session Timeout ', 401, res)
            return
        }
        if (!req.headers.token) {
            pu.error('Session Timeout ', 401, res)

            return
        }
        let ser_token = await redis.get('USER_TOKEN_' + req.headers.userid)
        if (!ser_token) {
            pu.error('Session Timeout ', 401, res)
            return
        }
        if (ser_token !== req.headers.token) {
            console.log(4)
            pu.error('Session Timeout ', 401, res)
            return
        }
    }
    await redis.set('USER_TOKEN_' + req.headers.userid, req.headers.token, 86400000)
    // next()
    // return
    /*验证权限
    * 1、白名单验证
    * 2、查询角色
    * 3、查询权限
    * 4、拼接所有权限
    * 5、验证
    * */

    let jur = config.jurlist

    var jurstatus = false
    for (var i = 0; i < jur.length; i++) {
        if (req.headers.server == jur[i][0]) {
            if (jur[i][1] == '*' || req.headers.function == jur[i][1]) { //跳出全部+
                jurstatus = true
            }

        }
    }
    if (jurstatus) {
        next()
        return
    }
    if (jurstatus === false) {

        if (!req.headers.module) {
            pu.fail('request module error ', res)
            return
        }
        if (!req.headers.team) {
            pu.fail('request team error ', res)
            return
        }

        if (!req.headers.uid) {
            pu.fail('request uid error ', res)
            return
        }

        var jurlist = []
        //获取全部角色
        let role = await redis.get('USER_ROLE_' + req.headers.uid)
        if (role) {
            role = role.split(',')
            //获取角色中全部权限
            for (var i = 0; i < role.length; i++) {
                let jurid = await redis.hget('JURINFO_ROLE_' + req.headers.team, role[i])
                if (jurid) {
                    jurid = jurid.split(',')
                    jurlist = jurlist.concat(jurid)
                }
            }
        }
        //获取单个权限
        let juid = await redis.hget('JURINFO_USER_' + req.headers.team, req.headers.uid)
        if (juid) {
            jurlist.push(juid)
        }
        console.log('权限id列表', jurlist.toString())
        var module = req.headers.module
        var server = req.headers.server
        var fun = req.headers.function
        var status = false
        if (!jurlist) {
            pu.error('No permission ', 402, res)
            return
        }
        for (var i = 0; i < jurlist.length; i++) {
            console.log('JURINFO_' + req.headers.team, jurlist[i])
            let info = await redis.hget('JURINFO_' + req.headers.team, jurlist[i])

            if (!info || !info.length) {
                console.log('没有权限')
                pu.error('No permission ', 402, res)
                return
            }
            console.log(JSON.stringify(info))
            info = JSON.parse(info)
            for (var j = 0; j < info.length; j++) {
                let obj = info[j]
                if (!obj) {
                    break
                }

                if (obj.module == module && obj.status == 1) { //拥有模块权限
                    console.log('拥有模块权限', module)
                    for (var k = 0; k < obj.jur.length; k++) {
                        if (!obj.jur[k]) {
                            break
                        }
                        if (obj.jur[k].server == server && obj.jur[k].status == 1) { //有server权限
                            console.log('拥有server权限', module)
                            for (var s = 0; s < obj.jur[k].jurlist.length; s++) {
                                if (!obj.jur[k].jurlist[s]) {
                                    break
                                }
                                console.log(obj.jur[k].type)
                                if ((obj.jur[k].type &&obj.jur[k].type== "temp")){
                                    continue;
                                }
                                if ((obj.jur[k].jurlist[s].function[0] == '*' || (obj.jur[k].jurlist[s].function == fun && obj.jur[k].jurlist[s].status == 1))) {//有接口权限

                                    console.log(obj.jur[k].jurlist[s].function, '鉴权通过')
                                    console.log(obj.jur[k].jurlist[s])
                                    console.log(obj.jur[k].jurlist[s].field)
                                    res.authentication = {}
                                    res.authentication.authentication = true
                                    res.authentication.field = obj.jur[k].field
                                    res.authentication.adopt = obj.jur[k].adopt
                                    status = true
                                    next()
                                    return
                                }
                            }
                        }
                    }
                }
                console.log(1)
                for (var k = 0; k < obj.jur.length; k++) {
                    //&& (obj.jur[k].function == fun)
                    if(!obj.jur[k].jurlist){
                        continue;
                    }




                    for (var s = 0; s < obj.jur[k].jurlist.length; s++) {
                        if (!obj.jur[k].jurlist[s]) {
                            break
                        }
                        if(obj.jur[k].type == "temp" && obj.jur[k].status == 1&&(obj.jur[k].jurlist[s].function == fun && obj.jur[k].jurlist[s].status == 1)){
                            console.log("找到權限")
                            console.log(obj.jur[k].jurlist[s].function, '鉴权通过')
                            console.log(obj.jur[k].jurlist[s])
                            console.log(obj.jur[k].jurlist[s].field)
                            res.authentication = {}
                            res.authentication.authentication = true
                            res.authentication.field = obj.jur[k].field
                            res.authentication.adopt = obj.jur[k].adopt
                            status = true
                            next()
                            return
                        }else{

                        }
                    }
                    console.log(obj.jur[k].server,obj.jur[k].type)
                }
            }
        }
        if (status === false) {
            console.log("没有权限",3);
            pu.error('No permission ', 402, res)
            return
        }
    }
})
require('./module/module')(app) //载入路由
// catch 404 and forward to error handler
app.use(function (req, res, next) {
    next(createError(404))
})
// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    console.log(err)
    res.locals.message = err.message
    if (res.locals.message != 'Not Found') {
        console.error(res.locals)
    }
    res.locals.error = req.app.get('env') === 'development' ? err : {}
    // render the error page
    res.status(err.status || 500)
    res.render('error')
})

/*捕捉全局错误 防止宕机*/
process.on('uncaughtException', function (err) {
    console.error('Caught exception: ' + err.toString())
})
module.exports = app

